﻿#include "mysqlite.h"

MySQLite::MySQLite(QObject *parent) : QThread(parent)
{
    start();
}

MySQLite::~MySQLite()
{
    //停止线程
    m_mutex.lock();
    m_stop = true;
    m_condition.wakeOne();
    m_mutex.unlock();

    //等待线程退出
    wait();

    //关闭数据库连接
    if (m_db.isOpen()) {
        m_db.close();
    }
}

//创建数据库
void MySQLite::createDatabase(const QString &dbName)
{
    QMutexLocker locker(&m_mutex);
    m_currentOp = Op_CreateDB;
    m_dbName = dbName;
    m_condition.wakeOne();
}

//写入单条数据
void MySQLite::writeSingleData(const SensorData &data)
{
    QMutexLocker locker(&m_mutex);
    m_currentOp = Op_WriteSingle;
    m_singleData = data;
    m_condition.wakeOne();
}

//写入多条数据
void MySQLite::writeBatchData(const QList<SensorData> &dataList)
{
    QMutexLocker locker(&m_mutex);
    m_currentOp = Op_WriteBatch;
    m_batchData = dataList;
    m_condition.wakeOne();
}

//线程运行函数
void MySQLite::run()
{
    while (!m_stop)
    {
        m_mutex.lock();
        // 等待操作请求
        if (m_currentOp == Op_None)
            m_condition.wait(&m_mutex);

        // 处理当前操作
        switch (m_currentOp)
        {
        case Op_CreateDB:
            createDBInternal(m_dbName);
            break;
        case Op_WriteSingle:
            if (!m_currentDB.isEmpty() && m_db.isOpen())
                writeSingleInternal(m_singleData);
            else
                qWarning() << u8"数据库未初始化，无法写入数据";
            break;
        case Op_WriteBatch:
            if (!m_currentDB.isEmpty() && m_db.isOpen())
                writeBatchInternal(m_batchData);
            else
                qWarning() << u8"数据库未初始化，无法批量写入数据";
            break;
        default:
            break;
        }

        //重置操作状态
        m_currentOp = Op_None;
        m_mutex.unlock();
    }
}

//内部功能，创建数据库和表结构
bool MySQLite::createDBInternal(const QString &dbName)
{
    //检查数据库是否已存在
    bool dbExists = QFile::exists(dbName);

    //如果已存在且当前已连接该数据库，直接返回
    if (dbExists && m_currentDB == dbName && m_db.isOpen())
    {
        qDebug() << u8"数据库已存在，直接使用：" << dbName;
        emit signals_dbCreateFinished(true, dbName); //创建成功
        return true;
    }

    //关闭当前数据库连接
    if (m_db.isOpen())
    {
        m_db.close();
        QSqlDatabase::removeDatabase(m_currentDB);
    }

    //建立新连接
    m_db = QSqlDatabase::addDatabase("QSQLITE", dbName); //使用数据库名作为连接名
    m_db.setDatabaseName(dbName);

    if (!m_db.open())
    {
        qWarning() << u8"数据库打开失败：" << m_db.lastError().text();
        emit signals_dbCreateFinished(false, dbName); //创建失败
        return false;
    }

    //如果是新数据库，创建表结构
    if (!dbExists)
    {
        QSqlQuery query(m_db);
        //创建数据表（包含时间、温度1、温度2、压力、流量等字段）
        QString createSql = "CREATE TABLE IF NOT EXISTS sensor_data ("
                           "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                           "timestamp DATETIME NOT NULL, "
                           "temp1 REAL, "
                           "temp2 REAL, "
                           "pressure REAL, "
                           "flow REAL)";

        if (!query.exec(createSql))
        {
            qWarning() << u8"创建数据表失败：" << query.lastError().text();
            m_db.close();
            emit signals_dbCreateFinished(false, dbName); //创建失败
            return false;
        }
        qDebug() << u8"新数据库创建成功：" << dbName;
    }
    else
    {
        qDebug() << u8"使用现有数据库：" << dbName;
    }

    m_currentDB = dbName;
    emit signals_dbCreateFinished(true, dbName); //创建成功
    return true;
}

//内部功能，写入单条数据
bool MySQLite::writeSingleInternal(const SensorData &data)
{
    QSqlQuery query(m_db);
    //预处理SQL语句
    query.prepare("INSERT INTO sensor_data "
                 "(timestamp, temp1, temp2, pressure, flow) "
                 "VALUES (:timestamp, :temp1, :temp2, :pressure, :flow)");

    //绑定参数
    query.bindValue(":timestamp", data.timestamp.toString("yyyy-MM-dd HH:mm:ss.zzz"));
    query.bindValue(":temp1", data.temp1);
    query.bindValue(":temp2", data.temp2);
    query.bindValue(":pressure", data.pressure);
    query.bindValue(":flow", data.flow);

    if (!query.exec())
    {
        qWarning() << u8"单条数据写入失败：" << query.lastError().text();
        emit signals_dataWriteFinished(false);
        return false;
    }
    emit signals_dataWriteFinished(true);
    return true;
}

// 内部实现：写入多条数据
bool MySQLite::writeBatchInternal(const QList<SensorData> &dataList)
{
    if (dataList.isEmpty()) return true;

    //开启事务提升性能
    if (!m_db.transaction())
    {
        qWarning() << u8"开启事务失败：" << m_db.lastError().text();
        emit signals_dataWriteFinished(false);
        return false;
    }

    QSqlQuery query(m_db);
    query.prepare(u8"INSERT INTO sensor_data "
                 "(timestamp, temp1, temp2, pressure, flow) "
                 "VALUES (:timestamp, :temp1, :temp2, :pressure, :flow)");

    bool allSuccess = true;
    for (const auto &data : dataList)
    {
        query.bindValue(":timestamp", data.timestamp.toString("yyyy-MM-dd HH:mm:ss.zzz"));
        query.bindValue(":temp1", data.temp1);
        query.bindValue(":temp2", data.temp2);
        query.bindValue(":pressure", data.pressure);
        query.bindValue(":flow", data.flow);

        if (!query.exec())
        {
            qWarning() << u8"批量数据写入失败：" << query.lastError().text();
            allSuccess = false;
            break;
        }
    }

    //根据结果提交或回滚事务
    if (allSuccess)
    {
        m_db.commit();
        emit signals_dataWriteFinished(true);
        qDebug() << u8"批量写入成功，共" << dataList.size() << u8"条数据";
    }
    else
    {
        m_db.rollback();
        emit signals_dataWriteFinished(false);
        qWarning() << u8"批量写入失败，已回滚";
    }

    return allSuccess;
}
